package com.crb.oauth2.api.dingding;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiSnsGetuserinfoBycodeRequest;
import com.dingtalk.api.request.OapiUserGetRequest;
import com.dingtalk.api.request.OapiUserGetUseridByUnionidRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiSnsGetuserinfoBycodeResponse;
import com.dingtalk.api.response.OapiUserGetResponse;
import com.dingtalk.api.response.OapiUserGetUseridByUnionidResponse;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.taobao.api.ApiException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * Package: com.gulimall.thrid.party.dingding
 * Description： 钉钉推送以及授權工具
 * Author: huangjian
 * Date:  2020/6/30 20:53
 * Modified By:
 * @author huangjian
 */
@Component
public class DingDingTools {

    private  LoadingCache<String, String> cache;

    private static final String CACHE_ACCESS_TOKEN="cache_access_token";

    @Autowired
    private DingDingConfig dingDingConfig;

    /**
     * 本地緩存
     */
    @PostConstruct
    public void init()
    {
        /**
         * 7100秒自动过期
         */
        cache = CacheBuilder.newBuilder().expireAfterWrite(7100, TimeUnit.SECONDS).build(new CacheLoader<String, String>() {
            public String load(String id) throws Exception
            {
                return cache.get(id);
            }
        });
    }

    /**
     * 獲取access_token
     * @return
     * @throws ApiException
     */
    public  String getAccess_token() throws ApiException {
        // 获取缓存
        String cache_access_token = cache.getIfPresent(CACHE_ACCESS_TOKEN);
        if(StringUtils.isNotEmpty(cache_access_token)){
            System.out.println("命中緩存——>"+cache_access_token);
            return cache_access_token;
        }else{
            System.out.println("遠程查詢");
            DingDingConfig.Api api = dingDingConfig.getApi();
            DefaultDingTalkClient client = new DefaultDingTalkClient(api.getUrl().getGettoken());
            OapiGettokenRequest request = new OapiGettokenRequest();
            request.setAppkey(api.getAppkey());
            request.setAppsecret(api.getAppsecret());
            request.setHttpMethod("GET");
            OapiGettokenResponse response = client.execute(request);
            String accessToken = response.getAccessToken();
            // 放入缓存
            cache.put(CACHE_ACCESS_TOKEN, accessToken);
            return accessToken;
        }
    }

    /**
     * oauth2 回調回來，通過code換取unionid
     * @param code
     * @return
     * @throws ApiException
     */
    public OapiSnsGetuserinfoBycodeResponse getUserInfo(String code) throws ApiException {
        DingDingConfig.Api.Url url = dingDingConfig.getApi().getUrl();
        DefaultDingTalkClient client = new DefaultDingTalkClient(url.getGetuserinfo_bycode());
        OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest();
        req.setTmpAuthCode(code);
        DingDingConfig.Oauth2 oauth2 = dingDingConfig.getOauth2();
        OapiSnsGetuserinfoBycodeResponse response = client.execute(req, oauth2.getAppkey(), oauth2.getAppsecret());
        return response;
    }

    /**
     * 通過unionid換取userId
     * @param unionid
     * @return
     * @throws ApiException
     */
    public String getUserId(String unionid) throws ApiException {
        DingDingConfig.Api.Url url = dingDingConfig.getApi().getUrl();
        DingTalkClient client = new DefaultDingTalkClient(url.getGetUseridByUnionid());
        OapiUserGetUseridByUnionidRequest request = new OapiUserGetUseridByUnionidRequest();
        request.setUnionid(unionid);
        request.setHttpMethod("GET");
        OapiUserGetUseridByUnionidResponse response = client.execute(request, getAccess_token());
        return response.getUserid();
    }

    /**
     * 通過userId換取用戶基本信息
     * @param userId
     * @return
     * @throws ApiException
     */
    public OapiUserGetResponse getUser(String userId) throws ApiException {
        DingDingConfig.Api.Url url = dingDingConfig.getApi().getUrl();
        DingTalkClient client = new DefaultDingTalkClient(url.getUser_get());
        OapiUserGetRequest request = new OapiUserGetRequest();
        request.setUserid(userId);
        request.setHttpMethod("GET");
        OapiUserGetResponse response = client.execute(request, getAccess_token());
        return response;
    }

    /**
     * 通過unionid獲取用戶基本信息
     * @param unionid
     * @return
     * @throws ApiException
     */
    public OapiUserGetResponse getUserByUnionid(String unionid) throws ApiException {
        return getUser(getUserId(unionid));
    }

}
